package com.xique.door.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.door.bean.domain.*;
import com.xique.door.bean.request.commandV1.DeviceCommandDeleteNewRequest;
import com.xique.door.bean.request.commandV1.DeviceCommandDeleteRequest;
import com.xique.door.bean.request.commandV1.DeviceCommandDownloadRequest;
import com.xique.door.bean.request.commandV1.DeviceCommandGetRecStatusRequest;
import com.xique.door.bean.request.permissionGroup.PermissionGroupUserRequest;
import com.xique.door.bean.search.UserDeviceSearch;
import com.xique.door.biz.service.IDeviceCommandNewService;
import com.xique.door.biz.service.IDeviceCommandService;
import com.xique.door.constant.AccessCommandConstant;
import com.xique.door.constant.AccessDeviceConstant;
import com.xique.door.constant.UserConstant;
import com.xique.door.device.command.AccessCommandHQService;
import com.xique.door.device.freeview.constant.CommandCardType;
import com.xique.door.device.freeview.service.biz.FreeviewCommandBizService;
import com.xique.door.device.hq.bean.dto.HQResultDTO;
import com.xique.door.device.hq.bean.dto.HQResultDataDTO;
import com.xique.door.event.DelUserBatchCommandEvent;
import com.xique.door.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@EnableAsync
@Service
@Deprecated
public class DeviceCommandServiceImpl implements IDeviceCommandService {

    @Autowired
    private IUserService userService;

    @Autowired
    private AccessCommandHQService accessCommandService;

    @Autowired
    private IPermissionGroupUserService permissionGroupUserService;

    @Autowired
    private IPermissionGroupDeviceService permissionGroupDeviceService;

    @Autowired
    private IAccessDeviceService accessDeviceService;

    @Autowired
    private IUserDeviceService userDeviceService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private IDeviceCommandNewService deviceCommandNewService;

    @Autowired
    private IDCardService dCardService;

    @Autowired
    private IPermissionGroupService permissionGroupService;

    @Autowired
    private FreeviewCommandBizService freeviewCommandBizService;

    /**
     * 下发用户信息到设备
     * @param request
     * @return
     */
    @Override
    public AjaxResult downloadUserInfo(DeviceCommandDownloadRequest request) {

        Long groupId = request.getGroupId();
        Long userId = request.getUserId();
        Long parkId = request.getParkId();

        User user = userService.selectUserById(userId);

        if (null == user) {
            return AjaxResult.error("未找到对应用户");
        }

        if ("pause".equals(user.getStatus())) {
            return AjaxResult.error("该用户已被禁用");
        }

        if (StringUtils.isEmpty(user.getFaceUrl())){
            return AjaxResult.error("用户图片未上传！");
        }

        PermissionGroupUser permissionGroupUser = new PermissionGroupUser();
        permissionGroupUser.setUserId(request.getUserId());
        List<PermissionGroupUser> permissionGroupUsers = permissionGroupUserService.selectPermissionGroupUserList(permissionGroupUser);
        if (permissionGroupUsers.isEmpty()){
            return AjaxResult.error("该用户没有绑定权限组");
        }

        List<String> deviceSns = getDevSns(parkId, userId, groupId);
        if (deviceSns.isEmpty()) {
            return AjaxResult.error("该权限组没有添加设备");
        }

//        Object obj = accessCommandService.downCardInfos(deviceSns, user, AccessCommandConstant.VERSION);
//        getReturn(JSONObject.parseObject(obj.toString(), HQResultDTO.class))
        if (groupId != null){
            user.setPermissionGroup(String.valueOf(groupId));
        }
        AjaxResult result = deviceCommandNewService.personCardCommand(user);
        return result;
    }

    /**
     * 下发卡片信息到设备
     * @param request
     * @return
     */
    @Override
    public AjaxResult downloadDCardInfo(DeviceCommandDownloadRequest request) {

        Long groupId = request.getGroupId();
        Long parkId = request.getParkId();
        Long cardId = request.getCardId();
        DCard dCard = dCardService.selectDCardById(cardId);
        Long userId = dCard.getUserId();

        User user = userService.selectUserById(userId);

        if (null == user) {
            return AjaxResult.error("未找到对应用户");
        }

        if ("pause".equals(user.getStatus())) {
            return AjaxResult.error("该用户已被禁用");
        }

        PermissionGroupUser permissionGroupUser = new PermissionGroupUser();
        permissionGroupUser.setUserId(userId);
        List<PermissionGroupUser> permissionGroupUsers = permissionGroupUserService.selectPermissionGroupUserList(permissionGroupUser);
        if (permissionGroupUsers.isEmpty()){
            return AjaxResult.error("该用户没有绑定权限组");
        }

        List<String> deviceSns = getDevSns(parkId, userId, groupId);
        if (deviceSns.isEmpty()) {
            return AjaxResult.error("该权限组没有添加设备");
        }

//        Object obj = accessCommandService.downCardInfos(deviceSns, user, AccessCommandConstant.VERSION);
//        getReturn(JSONObject.parseObject(obj.toString(), HQResultDTO.class))
        AjaxResult result = deviceCommandNewService.personCardCommand(user,dCard, CommandCardType.DOWN_CARD);
        return result;
    }

    /**
     * 下发全部用户信息到设备
     * @param request
     * @return
     */
    @Override
    public AjaxResult downloadAllUserInfo(DeviceCommandDownloadRequest request) {

        Long groupId = request.getGroupId();

        PermissionGroupUser groupUserSearch = new PermissionGroupUser();
        groupUserSearch.setGroupId(groupId);
        List<PermissionGroupUser> groupUserList = permissionGroupUserService.selectPermissionGroupUserList(groupUserSearch);

        List<Long> userIds = groupUserList.stream().map(PermissionGroupUser::getUserId).collect(Collectors.toList());

        if (userIds.isEmpty()) {
            return AjaxResult.error("未找到对用用户");
        }

        List<User> userList = userService.selectUserByIds(userIds, UserConstant.Status.NORMAL);

        List<String> deviceSns = getDevSns(request.getParkId(), null, groupId);

        if (deviceSns.isEmpty()) {
            return AjaxResult.error("该权限组没有添加设备");
        }

        List<PermissionGroupDevice> permissionGroupDeviceList = permissionGroupDeviceService.selectPermissionGroupDeviceListByGroupIds(Collections.singletonList(groupId));
        List<PermissionGroupDevice> hqPermissionGroupDeviceList = permissionGroupDeviceList.stream().filter(item -> AccessCommandConstant.DeviceType.HQ.equals(item.getDevModel())).collect(Collectors.toList());
        List<PermissionGroupDevice> freeviewPermissionGroupDeviceList = permissionGroupDeviceList.stream().filter(item -> AccessCommandConstant.DeviceType.FREEVIEW_45.equals(item.getDevModel())).collect(Collectors.toList());

//        if (!hqPermissionGroupDeviceList.isEmpty()) {
//            List<String> devSns = hqPermissionGroupDeviceList.stream().map(PermissionGroupDevice::getDevSn).collect(Collectors.toList());
//            Object obj = accessCommandService.downBatchUserInfos(devSns, userList, AccessCommandConstant.VERSION);
//            AjaxResult result = getReturn(JSONObject.parseObject(obj.toString(), HQResultDTO.class));
//            if (AjaxResult.isError(result)){
//                return result;
//            }
//        }

//        if (!freeviewPermissionGroupDeviceList.isEmpty()) {
//            for (PermissionGroupDevice device : freeviewPermissionGroupDeviceList) {
//                Object o = freeviewCommandBizService.downUsers(device, userList);
//            }
//        }

//        if (!freeviewPermissionGroupDeviceList.isEmpty()){
//            List<String> devSns = freeviewPermissionGroupDeviceList.stream().map(PermissionGroupDevice::getDevSn).collect(Collectors.toList());
//            Object obj = freeviewCommandBizService.downCardInfos(devSns, userList);
//            AjaxResult result = getReturn(JSONObject.parseObject(obj.toString(), HQResultDTO.class));
//            if (AjaxResult.isError(result)){
//                return result;
//            }
//        }

        return AjaxResult.success("下发成功");
    }

    /**
     * 下发所有卡片到设备
     * 1、查询该权限组下的所有卡片；
     * 2、批量下发到设备
     * @param request
     * @return
     */
    @Override
    public AjaxResult downloadAllCardInfo(DeviceCommandDownloadRequest request) {
        Long groupId = request.getGroupId();
        PermissionGroupUserRequest request1 = new PermissionGroupUserRequest();
        request1.setGroupId(request.getGroupId());
        request1.setParkId(request.getParkId());
        List<PermissionGroupDCard> list = permissionGroupService.selectAllocatedDCardList(request1);
        List<Long> cardIds = list.stream().map(PermissionGroupDCard::getCardId).collect(Collectors.toList());

        if (cardIds.isEmpty()) {
            return AjaxResult.error("未找到对用卡片");
        }

        List<DCard> dCardList = dCardService.selectDCardByIds(cardIds, UserConstant.Status.NORMAL);

//        List<String> deviceSns = getDevSns(request.getParkId(), null, groupId);
        List<PermissionGroupDevice> permissionGroupDeviceList = permissionGroupDeviceService.selectPermissionGroupDeviceListByGroupIds(Collections.singletonList(groupId));

        List<String> hqDevSns  = permissionGroupDeviceList.stream().filter(item -> AccessCommandConstant.DeviceType.HQ.equals(item.getDevModel())).map(PermissionGroupDevice::getDevSn).collect(Collectors.toList());
        List<String> freeviewDevSns  = permissionGroupDeviceList.stream().filter(item -> AccessCommandConstant.DeviceType.FREEVIEW_45.equals(item.getDevModel())).map(PermissionGroupDevice::getDevSn).collect(Collectors.toList());
        if (permissionGroupDeviceList.isEmpty()) {
            return AjaxResult.error("该权限组没有添加设备");
        }
        if (!freeviewDevSns.isEmpty()) {
            Object o = freeviewCommandBizService.downCardInfos(freeviewDevSns, dCardList);
            AjaxResult result =  getReturn(JSONObject.parseObject(o.toString(), HQResultDTO.class));
            if (AjaxResult.isError(result)){
                return result;
            }
        }
        if (!hqDevSns.isEmpty()) {
            Object obj = accessCommandService.downBatchDCardInfos(hqDevSns, dCardList, AccessCommandConstant.VERSION);
            AjaxResult result = getReturn(JSONObject.parseObject(obj.toString(), HQResultDTO.class));
            if (AjaxResult.isError(result)){
                return result;
            }
        }
        return AjaxResult.success("同步命令已下发");
    }

    /**
     * 获取返回数据
     * @author shd
     * @date 2021/7/5 9:12
     * @param dto hq设备dto
     * @return com.ruoyi.common.core.domain.AjaxResult
     */
    public AjaxResult getReturn(HQResultDTO dto) {
        if (0 != dto.getResult_code()) {
            return AjaxResult.error("下发失败");
        }

        List<String> messages = new ArrayList<>();

        for (HQResultDataDTO data : dto.getData()) {
            String message = "";
            if (!data.getStatus().equals(AccessCommandConstant.DeviceStatus.SUCCESS)) {
                message = data.getDeviceCode() + ":" + data.getMsg() + (data.getResult() != null ?  " 具体原因：" + data.getResult().getInfo().getDetail() : "") + "<br/>";
            } else {
                message = data.getDeviceCode() + ":" + data.getMsg() + "<br/>";
            }
            messages.add(message);
        }
        return AjaxResult.success(String.join("", messages));
    }

    /**
     * 获取设备sn
     * 根据传入的参数获取不同级别的数据 parkId,groupId,userId都不为null：某个权限组下该用户所持有的设备；
     * userId为null：某个权限组所有持有的设备；groupId为null：某个用户所有持有的设备；
     * groupId,userId为null，某个项目所有持有的设备；parkId,groupId为null，某个用户所有项目持有的设备（正常场景不会出现）
     * @author shd
     * @date 2021/7/5 9:13
     * @param parkId 项目ID
     * @param userId 用户ID
     * @param groupId 权限组ID
     * @return java.util.List<java.lang.String>
     */
    @Override
    public List<String> getDevSns(Long parkId, Long userId, Long groupId) {
        UserDevice search = new UserDevice();
        search.setParkId(parkId);
        search.setUserId(userId);
        search.setGroupId(groupId);
        List<UserDevice> deviceList = userDeviceService.selectUserDeviceList(search);

        return deviceList.stream().map(UserDevice::getDevSn).distinct().collect(Collectors.toList());
        /*
        if (null != groupId) {
            List<PermissionGroupDevice> deviceList = permissionGroupDeviceService.selectPermissionGroupDeviceListByGroupIds(Arrays.asList(groupId));
            if (deviceList.isEmpty()) {
                return new ArrayList<>();
            }
            List<Long> deviceIds = deviceList.stream().map(PermissionGroupDevice::getDeviceId).collect(Collectors.toList());

            List<AccessDevice> devices = accessDeviceService.selectAccessDeviceByIds(deviceIds, AccessDeviceConstant.DeviceStatus.NORMAL);

            return devices.stream().map(AccessDevice::getDevSn).collect(Collectors.toList());
        } else {
            UserDevice search = new UserDevice();
            search.setParkId(parkId);
            search.setUserId(userId);
            List<UserDevice> deviceList = userDeviceService.selectUserDeviceList(search);

            return deviceList.stream().map(UserDevice::getDevSn).collect(Collectors.toList());
        }
         */
    }

    @Override
    public List<String> getDevSns(Long parkId, Long groupId, List<Long> userIds) {

        UserDeviceSearch search = new UserDeviceSearch();
        search.setParkId(parkId);
        search.setGroupId(groupId);
        search.setUserIds(userIds);
        List<UserDevice> list = userDeviceService.selectUserDeviceListBySearch(search);

        return list.stream().map(UserDevice::getDevSn).distinct().collect(Collectors.toList());
    }

    /**
     * 获取用户设备状态
     * @author shd
     * @date 2021/7/5 9:21
     * @param request 入参
     * @return java.util.List<com.jzy.oms.access.permissionGroup.user.bean.domain.PermissionGroupUser>
     */
    @Override
    public List<PermissionGroupUser> getRecStatus(DeviceCommandGetRecStatusRequest request) {

        List<PermissionGroupDevice> groupDevices = permissionGroupDeviceService.selectPermissionGroupDeviceListByGroupIds(Arrays.asList(request.getGroupId()));
        List<Long> deviceIds = groupDevices.stream().map(PermissionGroupDevice::getDeviceId).collect(Collectors.toList());
        List<AccessDevice> devices = accessDeviceService.selectAccessDeviceByIds(deviceIds, AccessDeviceConstant.DeviceStatus.NORMAL);
        List<String> devSns = devices.stream().map(AccessDevice::getDevSn).collect(Collectors.toList());
        List<String> customIds = request.getUsers().stream().map(PermissionGroupUser::getCustomId).collect(Collectors.toList());

        Object obj = new Object();
        try {
            obj = accessCommandService.getRecStatus(request.getClassName(), devSns, customIds, AccessCommandConstant.VERSION);
        } catch (Exception e) {
            e.printStackTrace();
        }

        HQResultDTO dto = JSONObject.parseObject(obj.toString(), HQResultDTO.class);

        Map<String, Object> result = dto.getData_obj().getResult();

        request.getUsers().stream().forEach(item -> {
            item.setCommandStatus((!result.isEmpty() && null != item.getCustomId()) ? result.get(item.getCustomId()).toString() : null);
        });

        return request.getUsers();
    }

    /**
     * 获取海清卡片下发设备状态
     * @param request
     * @return
     */
    @Override
    public List<PermissionGroupDCard> getDCardRecStatus(DeviceCommandGetRecStatusRequest request) {
        List<PermissionGroupDevice> groupDevices = permissionGroupDeviceService.selectPermissionGroupDeviceListByGroupIds(Arrays.asList(request.getGroupId()));
        List<Long> deviceIds = groupDevices.stream().map(PermissionGroupDevice::getDeviceId).collect(Collectors.toList());
        List<AccessDevice> devices = accessDeviceService.selectAccessDeviceByIds(deviceIds, AccessDeviceConstant.DeviceStatus.NORMAL);
        List<String> devSns = devices.stream().map(AccessDevice::getDevSn).collect(Collectors.toList());
        List<String> customIds = request.getCards().stream().map(PermissionGroupDCard::getCustomId).collect(Collectors.toList());
        Object obj = new Object();
        try {
            obj = accessCommandService.getRecStatus(request.getClassName(), devSns, customIds, AccessCommandConstant.VERSION);
        } catch (Exception e) {
            e.printStackTrace();
        }

        HQResultDTO dto = JSONObject.parseObject(obj.toString(), HQResultDTO.class);

        Map<String, Object> result = dto.getData_obj().getResult();

        request.getCards().stream().forEach(item -> {
            item.setCommandStatus((!result.isEmpty() && null != item.getCustomId()) ? result.get(item.getCustomId()).toString() : null);
        });

        return request.getCards();
    }

    /**
     * 删除用户信息下发到设备
     * @author shd
     * @date 2021/7/5 9:22
     * @param request
     * @return com.ruoyi.common.core.domain.AjaxResult
     */
    @Override
    public AjaxResult delUserInfo(DeviceCommandDeleteRequest request) {

        User user = userService.selectUserById(request.getUserId());
        if (null == user) {
            return null;
        }

        List<UserDevice> userDevices = new ArrayList<>();
        if (request.getGroupId() != null) {
            List<PermissionGroupDevice> groupDevices = permissionGroupDeviceService.selectPermissionGroupDeviceListByGroupIds(Arrays.asList(request.getGroupId()));
            List<Long> deviceIds = groupDevices.stream().map(PermissionGroupDevice::getDeviceId).collect(Collectors.toList());

            userDevices = userDeviceService.selectUserDeviceListByUserIdsAndDeviceIds(request.getParkId(), Arrays.asList(request.getUserId()), deviceIds);
        } else {
            UserDevice search = new UserDevice();
            search.setParkId(request.getParkId());
            search.setUserId(request.getUserId());
            userDevices = userDeviceService.selectUserDeviceList(search);
        }

        List<String> devSns = userDevices.stream().map(UserDevice::getDevSn).distinct().collect(Collectors.toList());

        if (devSns.isEmpty()) {
            return AjaxResult.success("删除完成");
        }

        Map<String, String> customIdMap = new HashMap<>();
        customIdMap.put("customId", user.getCustomId());

        Object obj = accessCommandService.delUserInfos(devSns, customIdMap, AccessCommandConstant.VERSION);

        return getReturn(JSONObject.parseObject(obj.toString(), HQResultDTO.class));
    }

    /**
     * 批量删除用户信息下发到设备
     * @author shd
     * @date 2021/7/5 9:23
     * @param request
     * @return com.ruoyi.common.core.domain.AjaxResult
     */
    @Override
    public AjaxResult delUserInfosCommand(DeviceCommandDeleteNewRequest request) {

        applicationContext.publishEvent(new DelUserBatchCommandEvent(request.getDeleteData()));

        return AjaxResult.success();
    }

    /**
     * 下发访客信息到设备
     * @author shd
     * @date 2021/7/5 9:24
     * @param request
     * @return com.ruoyi.common.core.domain.AjaxResult
     */
    @Override
    public AjaxResult downloadVisitorInfo(DeviceCommandDownloadRequest request) {

        UserDevice search = new UserDevice();
        search.setParkId(request.getParkId());
        search.setUserId(request.getUserId());
        List<UserDevice> userDevices = userDeviceService.selectUserDeviceList(search);
        List<String> devSns = userDevices.stream().map(UserDevice::getDevSn).distinct().collect(Collectors.toList());

        if (devSns.isEmpty()) {
            return AjaxResult.error("没有可以添加的设备");
        }

        Object obj = accessCommandService.downVisitorInfos(devSns, request.getVisitor(), AccessCommandConstant.VERSION);

        return getReturn(JSONObject.parseObject(obj.toString(), HQResultDTO.class));

    }
}
